applied patch from owen to get rid of accel map notifiers. changed things
authorTim Janik <timj@gtk.org>
Tue, 20 Nov 2001 23:43:03 +0000 (23:43 +0000)
committerTim Janik <timj@src.gnome.org>
Tue, 20 Nov 2001 23:43:03 +0000 (23:43 +0000)
Tue Nov 20 21:25:08 2001  Tim Janik  <timj@gtk.org>

* applied patch from owen to get rid of accel map notifiers.
changed things to fix reentrancy and API as discussed on gtk-devel.

* gtk/gtkaccelgroup.[hc]:
(gtk_accel_group_finalize): unregister this accel group from all
accel map paths.
(accel_closure_invalidate): handle invalidation of closures by
disconnecting their accelerators.
(quick_accel_add): move closure connection and changed notification
into this function to reduce code duplication. don't emit change
notification on closurers without accelerators.
(quick_accel_remove): rewrite, do the exact opposite of quick_accel_add
for a GtkAccelGroupEntry.
(gtk_accel_group_connect): get rid of the accel_path_quark argument.
(gtk_accel_group_connect_by_path): new function to add accelerators
with an accel path.
(gtk_accel_group_disconnect_closure): new function, disconnect a
closure from of an accel group.
(gtk_accel_group_disconnect): loop over all closure for a accel_ley,
accel_mods pair and remove them.
(_gtk_accel_group_reconnect): new function that basically does
gtk_accel_group_disconnect_closure() and
gtk_accel_group_connect_by_path() once an accel path changed.
(gtk_accel_groups_disconnect_closure): remove this, there's
gtk_accel_group_disconnect_closure().

* gtk/gtkaccelmap.[hc]: keep list of accel groups per entry now,
nuke notifiers.
(_gtk_accel_path_is_valid): make this non-static for
gtkwidget.c and gtkaccelgroup.c assertions.
(gtk_accel_map_add_notifer): removed this function.
(gtk_accel_map_remove_notifer): same.
(_gtk_accel_map_add_group):
(_gtk_accel_map_remove_group): (un-)register accel groups, with
accel paths for correct propagation.
(gtk_accel_map_add_entry): return void.
(gtk_accel_map_lookup): return gboolean instead of GQuark.

* gtk/gtkitemfactory.c (gtk_item_factory_add_foreign): always
set accel_path on widgets.

* gtk/gtkwidget.[hc]:
(accel_path_changed): got rid of this, changes are handled by
accel maps internally now.
(_gtk_widget_set_accel_path): get things to work without notifiers.
(gtk_widget_list_accel_closures): list accel closures of a widget.

* gtk/gtkwindow.[hc]: rename ::accels_changed, to ::keys_changed.

25 files changed:
ChangeLog
ChangeLog.pre-2-0
ChangeLog.pre-2-10
ChangeLog.pre-2-2
ChangeLog.pre-2-4
ChangeLog.pre-2-6
ChangeLog.pre-2-8
docs/reference/gtk/gtk-sections.txt
docs/reference/gtk/tmpl/gtk-unused.sgml
docs/reference/gtk/tmpl/gtkaccelgroup.sgml
docs/reference/gtk/tmpl/gtkaccellabel.sgml
docs/reference/gtk/tmpl/gtkwidget.sgml
docs/reference/gtk/tmpl/gtkwindow.sgml
gtk/gtkaccelgroup.c
gtk/gtkaccelgroup.h
gtk/gtkaccellabel.c
gtk/gtkaccelmap.c
gtk/gtkaccelmap.h
gtk/gtkitemfactory.c
gtk/gtkmenu.c
gtk/gtkmenu.h
gtk/gtkwidget.c
gtk/gtkwidget.h
gtk/gtkwindow.c
gtk/gtkwindow.h

index 9915522ca4bf962567ad4e6a1f72c1c3f026ff32..fb08736ec1762f6d46a29fce082077adac127908 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,54 @@
+Tue Nov 20 21:25:08 2001  Tim Janik  <timj@gtk.org>
+
+       * applied patch from owen to get rid of accel map notifiers.
+       changed things to fix reentrancy and API as discussed on gtk-devel.
+
+       * gtk/gtkaccelgroup.[hc]:
+       (gtk_accel_group_finalize): unregister this accel group from all
+       accel map paths.
+       (accel_closure_invalidate): handle invalidation of closures by
+       disconnecting their accelerators.
+       (quick_accel_add): move closure connection and changed notification
+       into this function to reduce code duplication. don't emit change
+       notification on closurers without accelerators.
+       (quick_accel_remove): rewrite, do the exact opposite of quick_accel_add
+       for a GtkAccelGroupEntry.
+       (gtk_accel_group_connect): get rid of the accel_path_quark argument.
+       (gtk_accel_group_connect_by_path): new function to add accelerators
+       with an accel path.
+       (gtk_accel_group_disconnect_closure): new function, disconnect a
+       closure from of an accel group.
+       (gtk_accel_group_disconnect): loop over all closure for a accel_ley,
+       accel_mods pair and remove them.
+       (_gtk_accel_group_reconnect): new function that basically does
+       gtk_accel_group_disconnect_closure() and
+       gtk_accel_group_connect_by_path() once an accel path changed.
+       (gtk_accel_groups_disconnect_closure): remove this, there's
+       gtk_accel_group_disconnect_closure().
+       
+       * gtk/gtkaccelmap.[hc]: keep list of accel groups per entry now,
+       nuke notifiers.
+       (_gtk_accel_path_is_valid): make this non-static for
+       gtkwidget.c and gtkaccelgroup.c assertions.
+       (gtk_accel_map_add_notifer): removed this function.
+       (gtk_accel_map_remove_notifer): same.
+       (_gtk_accel_map_add_group):
+       (_gtk_accel_map_remove_group): (un-)register accel groups, with
+       accel paths for correct propagation.
+       (gtk_accel_map_add_entry): return void.
+       (gtk_accel_map_lookup): return gboolean instead of GQuark.
+       
+       * gtk/gtkitemfactory.c (gtk_item_factory_add_foreign): always
+       set accel_path on widgets.
+       
+       * gtk/gtkwidget.[hc]:
+       (accel_path_changed): got rid of this, changes are handled by
+       accel maps internally now.
+       (_gtk_widget_set_accel_path): get things to work without notifiers.
+       (gtk_widget_list_accel_closures): list accel closures of a widget.
+       
+       * gtk/gtkwindow.[hc]: rename ::accels_changed, to ::keys_changed.
+
 2001-11-20  Matthias Clasen  <matthiasc@poet.de>
 
        * gtk/gtkcontainer.c (gtk_container_propagate_expose): Typo fix.
index 9915522ca4bf962567ad4e6a1f72c1c3f026ff32..fb08736ec1762f6d46a29fce082077adac127908 100644 (file)
@@ -1,3 +1,54 @@
+Tue Nov 20 21:25:08 2001  Tim Janik  <timj@gtk.org>
+
+       * applied patch from owen to get rid of accel map notifiers.
+       changed things to fix reentrancy and API as discussed on gtk-devel.
+
+       * gtk/gtkaccelgroup.[hc]:
+       (gtk_accel_group_finalize): unregister this accel group from all
+       accel map paths.
+       (accel_closure_invalidate): handle invalidation of closures by
+       disconnecting their accelerators.
+       (quick_accel_add): move closure connection and changed notification
+       into this function to reduce code duplication. don't emit change
+       notification on closurers without accelerators.
+       (quick_accel_remove): rewrite, do the exact opposite of quick_accel_add
+       for a GtkAccelGroupEntry.
+       (gtk_accel_group_connect): get rid of the accel_path_quark argument.
+       (gtk_accel_group_connect_by_path): new function to add accelerators
+       with an accel path.
+       (gtk_accel_group_disconnect_closure): new function, disconnect a
+       closure from of an accel group.
+       (gtk_accel_group_disconnect): loop over all closure for a accel_ley,
+       accel_mods pair and remove them.
+       (_gtk_accel_group_reconnect): new function that basically does
+       gtk_accel_group_disconnect_closure() and
+       gtk_accel_group_connect_by_path() once an accel path changed.
+       (gtk_accel_groups_disconnect_closure): remove this, there's
+       gtk_accel_group_disconnect_closure().
+       
+       * gtk/gtkaccelmap.[hc]: keep list of accel groups per entry now,
+       nuke notifiers.
+       (_gtk_accel_path_is_valid): make this non-static for
+       gtkwidget.c and gtkaccelgroup.c assertions.
+       (gtk_accel_map_add_notifer): removed this function.
+       (gtk_accel_map_remove_notifer): same.
+       (_gtk_accel_map_add_group):
+       (_gtk_accel_map_remove_group): (un-)register accel groups, with
+       accel paths for correct propagation.
+       (gtk_accel_map_add_entry): return void.
+       (gtk_accel_map_lookup): return gboolean instead of GQuark.
+       
+       * gtk/gtkitemfactory.c (gtk_item_factory_add_foreign): always
+       set accel_path on widgets.
+       
+       * gtk/gtkwidget.[hc]:
+       (accel_path_changed): got rid of this, changes are handled by
+       accel maps internally now.
+       (_gtk_widget_set_accel_path): get things to work without notifiers.
+       (gtk_widget_list_accel_closures): list accel closures of a widget.
+       
+       * gtk/gtkwindow.[hc]: rename ::accels_changed, to ::keys_changed.
+
 2001-11-20  Matthias Clasen  <matthiasc@poet.de>
 
        * gtk/gtkcontainer.c (gtk_container_propagate_expose): Typo fix.
index 9915522ca4bf962567ad4e6a1f72c1c3f026ff32..fb08736ec1762f6d46a29fce082077adac127908 100644 (file)
@@ -1,3 +1,54 @@
+Tue Nov 20 21:25:08 2001  Tim Janik  <timj@gtk.org>
+
+       * applied patch from owen to get rid of accel map notifiers.
+       changed things to fix reentrancy and API as discussed on gtk-devel.
+
+       * gtk/gtkaccelgroup.[hc]:
+       (gtk_accel_group_finalize): unregister this accel group from all
+       accel map paths.
+       (accel_closure_invalidate): handle invalidation of closures by
+       disconnecting their accelerators.
+       (quick_accel_add): move closure connection and changed notification
+       into this function to reduce code duplication. don't emit change
+       notification on closurers without accelerators.
+       (quick_accel_remove): rewrite, do the exact opposite of quick_accel_add
+       for a GtkAccelGroupEntry.
+       (gtk_accel_group_connect): get rid of the accel_path_quark argument.
+       (gtk_accel_group_connect_by_path): new function to add accelerators
+       with an accel path.
+       (gtk_accel_group_disconnect_closure): new function, disconnect a
+       closure from of an accel group.
+       (gtk_accel_group_disconnect): loop over all closure for a accel_ley,
+       accel_mods pair and remove them.
+       (_gtk_accel_group_reconnect): new function that basically does
+       gtk_accel_group_disconnect_closure() and
+       gtk_accel_group_connect_by_path() once an accel path changed.
+       (gtk_accel_groups_disconnect_closure): remove this, there's
+       gtk_accel_group_disconnect_closure().
+       
+       * gtk/gtkaccelmap.[hc]: keep list of accel groups per entry now,
+       nuke notifiers.
+       (_gtk_accel_path_is_valid): make this non-static for
+       gtkwidget.c and gtkaccelgroup.c assertions.
+       (gtk_accel_map_add_notifer): removed this function.
+       (gtk_accel_map_remove_notifer): same.
+       (_gtk_accel_map_add_group):
+       (_gtk_accel_map_remove_group): (un-)register accel groups, with
+       accel paths for correct propagation.
+       (gtk_accel_map_add_entry): return void.
+       (gtk_accel_map_lookup): return gboolean instead of GQuark.
+       
+       * gtk/gtkitemfactory.c (gtk_item_factory_add_foreign): always
+       set accel_path on widgets.
+       
+       * gtk/gtkwidget.[hc]:
+       (accel_path_changed): got rid of this, changes are handled by
+       accel maps internally now.
+       (_gtk_widget_set_accel_path): get things to work without notifiers.
+       (gtk_widget_list_accel_closures): list accel closures of a widget.
+       
+       * gtk/gtkwindow.[hc]: rename ::accels_changed, to ::keys_changed.
+
 2001-11-20  Matthias Clasen  <matthiasc@poet.de>
 
        * gtk/gtkcontainer.c (gtk_container_propagate_expose): Typo fix.
index 9915522ca4bf962567ad4e6a1f72c1c3f026ff32..fb08736ec1762f6d46a29fce082077adac127908 100644 (file)
@@ -1,3 +1,54 @@
+Tue Nov 20 21:25:08 2001  Tim Janik  <timj@gtk.org>
+
+       * applied patch from owen to get rid of accel map notifiers.
+       changed things to fix reentrancy and API as discussed on gtk-devel.
+
+       * gtk/gtkaccelgroup.[hc]:
+       (gtk_accel_group_finalize): unregister this accel group from all
+       accel map paths.
+       (accel_closure_invalidate): handle invalidation of closures by
+       disconnecting their accelerators.
+       (quick_accel_add): move closure connection and changed notification
+       into this function to reduce code duplication. don't emit change
+       notification on closurers without accelerators.
+       (quick_accel_remove): rewrite, do the exact opposite of quick_accel_add
+       for a GtkAccelGroupEntry.
+       (gtk_accel_group_connect): get rid of the accel_path_quark argument.
+       (gtk_accel_group_connect_by_path): new function to add accelerators
+       with an accel path.
+       (gtk_accel_group_disconnect_closure): new function, disconnect a
+       closure from of an accel group.
+       (gtk_accel_group_disconnect): loop over all closure for a accel_ley,
+       accel_mods pair and remove them.
+       (_gtk_accel_group_reconnect): new function that basically does
+       gtk_accel_group_disconnect_closure() and
+       gtk_accel_group_connect_by_path() once an accel path changed.
+       (gtk_accel_groups_disconnect_closure): remove this, there's
+       gtk_accel_group_disconnect_closure().
+       
+       * gtk/gtkaccelmap.[hc]: keep list of accel groups per entry now,
+       nuke notifiers.
+       (_gtk_accel_path_is_valid): make this non-static for
+       gtkwidget.c and gtkaccelgroup.c assertions.
+       (gtk_accel_map_add_notifer): removed this function.
+       (gtk_accel_map_remove_notifer): same.
+       (_gtk_accel_map_add_group):
+       (_gtk_accel_map_remove_group): (un-)register accel groups, with
+       accel paths for correct propagation.
+       (gtk_accel_map_add_entry): return void.
+       (gtk_accel_map_lookup): return gboolean instead of GQuark.
+       
+       * gtk/gtkitemfactory.c (gtk_item_factory_add_foreign): always
+       set accel_path on widgets.
+       
+       * gtk/gtkwidget.[hc]:
+       (accel_path_changed): got rid of this, changes are handled by
+       accel maps internally now.
+       (_gtk_widget_set_accel_path): get things to work without notifiers.
+       (gtk_widget_list_accel_closures): list accel closures of a widget.
+       
+       * gtk/gtkwindow.[hc]: rename ::accels_changed, to ::keys_changed.
+
 2001-11-20  Matthias Clasen  <matthiasc@poet.de>
 
        * gtk/gtkcontainer.c (gtk_container_propagate_expose): Typo fix.
index 9915522ca4bf962567ad4e6a1f72c1c3f026ff32..fb08736ec1762f6d46a29fce082077adac127908 100644 (file)
@@ -1,3 +1,54 @@
+Tue Nov 20 21:25:08 2001  Tim Janik  <timj@gtk.org>
+
+       * applied patch from owen to get rid of accel map notifiers.
+       changed things to fix reentrancy and API as discussed on gtk-devel.
+
+       * gtk/gtkaccelgroup.[hc]:
+       (gtk_accel_group_finalize): unregister this accel group from all
+       accel map paths.
+       (accel_closure_invalidate): handle invalidation of closures by
+       disconnecting their accelerators.
+       (quick_accel_add): move closure connection and changed notification
+       into this function to reduce code duplication. don't emit change
+       notification on closurers without accelerators.
+       (quick_accel_remove): rewrite, do the exact opposite of quick_accel_add
+       for a GtkAccelGroupEntry.
+       (gtk_accel_group_connect): get rid of the accel_path_quark argument.
+       (gtk_accel_group_connect_by_path): new function to add accelerators
+       with an accel path.
+       (gtk_accel_group_disconnect_closure): new function, disconnect a
+       closure from of an accel group.
+       (gtk_accel_group_disconnect): loop over all closure for a accel_ley,
+       accel_mods pair and remove them.
+       (_gtk_accel_group_reconnect): new function that basically does
+       gtk_accel_group_disconnect_closure() and
+       gtk_accel_group_connect_by_path() once an accel path changed.
+       (gtk_accel_groups_disconnect_closure): remove this, there's
+       gtk_accel_group_disconnect_closure().
+       
+       * gtk/gtkaccelmap.[hc]: keep list of accel groups per entry now,
+       nuke notifiers.
+       (_gtk_accel_path_is_valid): make this non-static for
+       gtkwidget.c and gtkaccelgroup.c assertions.
+       (gtk_accel_map_add_notifer): removed this function.
+       (gtk_accel_map_remove_notifer): same.
+       (_gtk_accel_map_add_group):
+       (_gtk_accel_map_remove_group): (un-)register accel groups, with
+       accel paths for correct propagation.
+       (gtk_accel_map_add_entry): return void.
+       (gtk_accel_map_lookup): return gboolean instead of GQuark.
+       
+       * gtk/gtkitemfactory.c (gtk_item_factory_add_foreign): always
+       set accel_path on widgets.
+       
+       * gtk/gtkwidget.[hc]:
+       (accel_path_changed): got rid of this, changes are handled by
+       accel maps internally now.
+       (_gtk_widget_set_accel_path): get things to work without notifiers.
+       (gtk_widget_list_accel_closures): list accel closures of a widget.
+       
+       * gtk/gtkwindow.[hc]: rename ::accels_changed, to ::keys_changed.
+
 2001-11-20  Matthias Clasen  <matthiasc@poet.de>
 
        * gtk/gtkcontainer.c (gtk_container_propagate_expose): Typo fix.
index 9915522ca4bf962567ad4e6a1f72c1c3f026ff32..fb08736ec1762f6d46a29fce082077adac127908 100644 (file)
@@ -1,3 +1,54 @@
+Tue Nov 20 21:25:08 2001  Tim Janik  <timj@gtk.org>
+
+       * applied patch from owen to get rid of accel map notifiers.
+       changed things to fix reentrancy and API as discussed on gtk-devel.
+
+       * gtk/gtkaccelgroup.[hc]:
+       (gtk_accel_group_finalize): unregister this accel group from all
+       accel map paths.
+       (accel_closure_invalidate): handle invalidation of closures by
+       disconnecting their accelerators.
+       (quick_accel_add): move closure connection and changed notification
+       into this function to reduce code duplication. don't emit change
+       notification on closurers without accelerators.
+       (quick_accel_remove): rewrite, do the exact opposite of quick_accel_add
+       for a GtkAccelGroupEntry.
+       (gtk_accel_group_connect): get rid of the accel_path_quark argument.
+       (gtk_accel_group_connect_by_path): new function to add accelerators
+       with an accel path.
+       (gtk_accel_group_disconnect_closure): new function, disconnect a
+       closure from of an accel group.
+       (gtk_accel_group_disconnect): loop over all closure for a accel_ley,
+       accel_mods pair and remove them.
+       (_gtk_accel_group_reconnect): new function that basically does
+       gtk_accel_group_disconnect_closure() and
+       gtk_accel_group_connect_by_path() once an accel path changed.
+       (gtk_accel_groups_disconnect_closure): remove this, there's
+       gtk_accel_group_disconnect_closure().
+       
+       * gtk/gtkaccelmap.[hc]: keep list of accel groups per entry now,
+       nuke notifiers.
+       (_gtk_accel_path_is_valid): make this non-static for
+       gtkwidget.c and gtkaccelgroup.c assertions.
+       (gtk_accel_map_add_notifer): removed this function.
+       (gtk_accel_map_remove_notifer): same.
+       (_gtk_accel_map_add_group):
+       (_gtk_accel_map_remove_group): (un-)register accel groups, with
+       accel paths for correct propagation.
+       (gtk_accel_map_add_entry): return void.
+       (gtk_accel_map_lookup): return gboolean instead of GQuark.
+       
+       * gtk/gtkitemfactory.c (gtk_item_factory_add_foreign): always
+       set accel_path on widgets.
+       
+       * gtk/gtkwidget.[hc]:
+       (accel_path_changed): got rid of this, changes are handled by
+       accel maps internally now.
+       (_gtk_widget_set_accel_path): get things to work without notifiers.
+       (gtk_widget_list_accel_closures): list accel closures of a widget.
+       
+       * gtk/gtkwindow.[hc]: rename ::accels_changed, to ::keys_changed.
+
 2001-11-20  Matthias Clasen  <matthiasc@poet.de>
 
        * gtk/gtkcontainer.c (gtk_container_propagate_expose): Typo fix.
index 9915522ca4bf962567ad4e6a1f72c1c3f026ff32..fb08736ec1762f6d46a29fce082077adac127908 100644 (file)
@@ -1,3 +1,54 @@
+Tue Nov 20 21:25:08 2001  Tim Janik  <timj@gtk.org>
+
+       * applied patch from owen to get rid of accel map notifiers.
+       changed things to fix reentrancy and API as discussed on gtk-devel.
+
+       * gtk/gtkaccelgroup.[hc]:
+       (gtk_accel_group_finalize): unregister this accel group from all
+       accel map paths.
+       (accel_closure_invalidate): handle invalidation of closures by
+       disconnecting their accelerators.
+       (quick_accel_add): move closure connection and changed notification
+       into this function to reduce code duplication. don't emit change
+       notification on closurers without accelerators.
+       (quick_accel_remove): rewrite, do the exact opposite of quick_accel_add
+       for a GtkAccelGroupEntry.
+       (gtk_accel_group_connect): get rid of the accel_path_quark argument.
+       (gtk_accel_group_connect_by_path): new function to add accelerators
+       with an accel path.
+       (gtk_accel_group_disconnect_closure): new function, disconnect a
+       closure from of an accel group.
+       (gtk_accel_group_disconnect): loop over all closure for a accel_ley,
+       accel_mods pair and remove them.
+       (_gtk_accel_group_reconnect): new function that basically does
+       gtk_accel_group_disconnect_closure() and
+       gtk_accel_group_connect_by_path() once an accel path changed.
+       (gtk_accel_groups_disconnect_closure): remove this, there's
+       gtk_accel_group_disconnect_closure().
+       
+       * gtk/gtkaccelmap.[hc]: keep list of accel groups per entry now,
+       nuke notifiers.
+       (_gtk_accel_path_is_valid): make this non-static for
+       gtkwidget.c and gtkaccelgroup.c assertions.
+       (gtk_accel_map_add_notifer): removed this function.
+       (gtk_accel_map_remove_notifer): same.
+       (_gtk_accel_map_add_group):
+       (_gtk_accel_map_remove_group): (un-)register accel groups, with
+       accel paths for correct propagation.
+       (gtk_accel_map_add_entry): return void.
+       (gtk_accel_map_lookup): return gboolean instead of GQuark.
+       
+       * gtk/gtkitemfactory.c (gtk_item_factory_add_foreign): always
+       set accel_path on widgets.
+       
+       * gtk/gtkwidget.[hc]:
+       (accel_path_changed): got rid of this, changes are handled by
+       accel maps internally now.
+       (_gtk_widget_set_accel_path): get things to work without notifiers.
+       (gtk_widget_list_accel_closures): list accel closures of a widget.
+       
+       * gtk/gtkwindow.[hc]: rename ::accels_changed, to ::keys_changed.
+
 2001-11-20  Matthias Clasen  <matthiasc@poet.de>
 
        * gtk/gtkcontainer.c (gtk_container_propagate_expose): Typo fix.
index fc976556947d49b6635d253f85618f6df51bf034..40ea35c2f1ca1cebf145e62c987da4530656d5b0 100644 (file)
@@ -8,12 +8,14 @@ GtkAccelGroup
 gtk_accel_group_get_type
 gtk_accel_group_new
 gtk_accel_group_connect
+gtk_accel_group_connect_by_path
 gtk_accel_group_disconnect
+gtk_accel_group_disconnect_key
 gtk_accel_group_query
-gtk_accel_group_activate
-gtk_accel_groups_activate
 gtk_accel_group_lock
 gtk_accel_group_unlock
+gtk_accel_group_from_accel_closure
+gtk_accel_groups_activate
 gtk_accelerator_valid
 gtk_accelerator_parse
 gtk_accelerator_name
@@ -33,18 +35,16 @@ GTK_ACCEL_GROUP_GET_CLASS
 <SECTION>
 <FILE>gtkaccelmap</FILE>
 <TITLE>Accelerator Maps</TITLE>
-GtkAccelMapNotify
 GtkAccelMapForeach
 gtk_accel_map_add_entry
 gtk_accel_map_lookup_entry
 gtk_accel_map_change_entry
-gtk_accel_map_add_notifer
-gtk_accel_map_remove_notifer
 gtk_accel_map_load
 gtk_accel_map_save
 gtk_accel_map_foreach
 gtk_accel_map_load_fd
 gtk_accel_map_save_fd
+gtk_accel_map_load_scanner
 </SECTION>
 
 <SECTION>
@@ -52,8 +52,8 @@ gtk_accel_map_save_fd
 <TITLE>GtkAccelLabel</TITLE>
 GtkAccelLabel
 gtk_accel_label_new
-gtk_accel_label_get_accel_object
-gtk_accel_label_set_accel_object
+gtk_accel_label_get_accel_closure
+gtk_accel_label_set_accel_closure
 gtk_accel_label_get_accel_widget
 gtk_accel_label_set_accel_widget
 gtk_accel_label_get_accel_width
@@ -1290,9 +1290,6 @@ GtkItemFactoryEntry
 GtkItemFactoryItem
 gtk_item_factory_new
 gtk_item_factory_construct
-gtk_item_factory_parse_rc
-gtk_item_factory_parse_rc_string
-gtk_item_factory_parse_rc_scanner
 gtk_item_factory_add_foreign
 gtk_item_factory_from_widget
 gtk_item_factory_path_from_widget
@@ -1300,9 +1297,6 @@ gtk_item_factory_get_item
 gtk_item_factory_get_widget
 gtk_item_factory_get_widget_by_action
 gtk_item_factory_get_item_by_action
-gtk_item_factory_dump_items
-gtk_item_factory_dump_rc
-gtk_item_factory_print_func
 gtk_item_factory_create_item
 gtk_item_factory_create_items
 gtk_item_factory_create_items_ac
@@ -1674,7 +1668,6 @@ GTK_OBJECT_TYPE
 GTK_OBJECT_TYPE_NAME
 GtkObjectFlags
 GTK_OBJECT_FLAGS
-GTK_OBJECT_DESTROYED
 GTK_OBJECT_FLOATING
 GTK_OBJECT_CONNECTED
 GTK_OBJECT_SET_FLAGS
@@ -3467,8 +3460,7 @@ gtk_widget_get_child_requisition
 gtk_widget_size_allocate
 gtk_widget_add_accelerator
 gtk_widget_remove_accelerator
-gtk_widget_remove_accelerators
-gtk_widget_accelerator_signal
+gtk_widget_list_accel_closures
 gtk_widget_event
 gtk_widget_activate
 gtk_widget_reparent
@@ -3519,7 +3511,6 @@ gtk_widget_shape_combine_mask
 gtk_widget_path
 gtk_widget_class_path
 gtk_widget_get_composite_name
-gtk_widget_lock_accelerators
 gtk_widget_modify_style
 gtk_widget_get_modifier_style
 gtk_widget_modify_fg
@@ -3541,8 +3532,6 @@ gtk_widget_set_app_paintable
 gtk_widget_set_double_buffered
 gtk_widget_set_composite_name
 gtk_widget_set_scroll_adjustments
-gtk_widget_unlock_accelerators
-gtk_widget_accelerators_locked
 gtk_widget_mnemonic_activate
 gtk_widget_class_install_style_property
 gtk_widget_class_install_style_property_parser
index 3bb9d320f3e2f19e6164752ca65ee44a0628dd80..6f3500c43b91a889343df03d1a6ff5a9da35d58a 100644 (file)
@@ -514,6 +514,19 @@ This is a private struct used by GTK+ internally, don't worry about it.
 </para>
 
 
+<!-- ##### USER_FUNCTION GtkAccelMapNotify ##### -->
+<para>
+
+</para>
+
+@data: 
+@accel_path_quark: 
+@accel_key: 
+@accel_mods: 
+@accel_group: 
+@old_accel_key: 
+@old_accel_mods: 
+
 <!-- ##### ENUM GtkAnchorType ##### -->
 <para>
 
@@ -1299,6 +1312,13 @@ the #GtkAdjustment which sets the range of the scale.
 </para>
 
 
+<!-- ##### SIGNAL GtkWindow::accels-changed ##### -->
+<para>
+
+</para>
+
+@window: the object which received the signal.
+
 <!-- ##### ARG GtkWindow:auto-shrink ##### -->
 <para>
 If the window shrinks automatically when widgets within it shrink.
@@ -1484,6 +1504,25 @@ If the window shrinks automatically when widgets within it shrink.
 @accel_label: 
 @accel_object: 
 
+<!-- ##### FUNCTION gtk_accel_map_add_notifer ##### -->
+<para>
+
+</para>
+
+@accel_path: 
+@notify_data: 
+@notify_func: 
+@accel_group: 
+
+<!-- ##### FUNCTION gtk_accel_map_remove_notifer ##### -->
+<para>
+
+</para>
+
+@accel_path: 
+@notify_data: 
+@notify_func: 
+
 <!-- ##### FUNCTION gtk_arg_copy ##### -->
 <para>
 It will either copy data into an existing argument or allocate a new argument
index b069f7e7385605cc41ddeabbabfea3d353f74ead..f3973777661d2fecc201ba38f05e2ce439c89982 100644 (file)
@@ -64,23 +64,35 @@ An object representing and maintaining a group of accelerators.
 @accel_mods: 
 @accel_flags: 
 @closure: 
-@accel_path_quark: 
 <!-- # Unused Parameters # -->
+@accel_path_quark: 
 @path_quark: 
 
 
+<!-- ##### FUNCTION gtk_accel_group_connect_by_path ##### -->
+<para>
+
+</para>
+
+@accel_group: 
+@accel_path: 
+@closure: 
+
+
 <!-- ##### FUNCTION gtk_accel_group_disconnect ##### -->
 <para>
 
 </para>
 
 @accel_group: 
+@closure: 
+@Returns: 
+<!-- # Unused Parameters # -->
 @accel_key: 
 @accel_mods: 
-@Returns: 
 
 
-<!-- ##### FUNCTION gtk_accel_group_query ##### -->
+<!-- ##### FUNCTION gtk_accel_group_disconnect_key ##### -->
 <para>
 
 </para>
@@ -88,21 +100,19 @@ An object representing and maintaining a group of accelerators.
 @accel_group: 
 @accel_key: 
 @accel_mods: 
-@n_entries: 
 @Returns: 
 
 
-<!-- ##### FUNCTION gtk_accel_groups_activate ##### -->
+<!-- ##### FUNCTION gtk_accel_group_query ##### -->
 <para>
 
 </para>
 
-@acceleratable
+@accel_group
 @accel_key: 
 @accel_mods: 
+@n_entries: 
 @Returns: 
-<!-- # Unused Parameters # -->
-@object: 
 
 
 <!-- ##### FUNCTION gtk_accel_group_lock ##### -->
@@ -121,6 +131,28 @@ An object representing and maintaining a group of accelerators.
 @accel_group: 
 
 
+<!-- ##### FUNCTION gtk_accel_group_from_accel_closure ##### -->
+<para>
+
+</para>
+
+@closure: 
+@Returns: 
+
+
+<!-- ##### FUNCTION gtk_accel_groups_activate ##### -->
+<para>
+
+</para>
+
+@acceleratable: 
+@accel_key: 
+@accel_mods: 
+@Returns: 
+<!-- # Unused Parameters # -->
+@object: 
+
+
 <!-- ##### FUNCTION gtk_accelerator_valid ##### -->
 <para>
 
index 4587cf7515a57b2621dcda82c438de2b13e57f53..dac75d743851dd85f8b1adb16b2b1561ac0f0472 100644 (file)
@@ -94,6 +94,15 @@ Creates a new #GtkAccelLabel.
 @Returns: a new #GtkAccelLabel.
 
 
+<!-- ##### FUNCTION gtk_accel_label_set_accel_closure ##### -->
+<para>
+
+</para>
+
+@accel_label: 
+@closure: 
+
+
 <!-- ##### FUNCTION gtk_accel_label_get_accel_widget ##### -->
 <para>
 
index 76769b73b5220e8e7f73b711abaaf539ff084a54..dbe5a82a339a1cc694e4671b8aadd3a8c6ee7cc8 100644 (file)
@@ -530,6 +530,15 @@ GtkWidget
 @Returns: 
 
 
+<!-- ##### FUNCTION gtk_widget_list_accel_closures ##### -->
+<para>
+
+</para>
+
+@widget: 
+@Returns: 
+
+
 <!-- ##### FUNCTION gtk_widget_event ##### -->
 <para>
 
index b8111b43623a78a6e3aad49f260531a754738ce0..d5a4f464789d4cb12705721459ffe1619b3c47e6 100644 (file)
@@ -694,35 +694,35 @@ it's larger
 @height: 
 
 
-<!-- ##### SIGNAL GtkWindow::accels-changed ##### -->
+<!-- ##### SIGNAL GtkWindow::activate-default ##### -->
 <para>
 
 </para>
 
 @window: the object which received the signal.
 
-<!-- ##### SIGNAL GtkWindow::activate-default ##### -->
+<!-- ##### SIGNAL GtkWindow::activate-focus ##### -->
 <para>
 
 </para>
 
 @window: the object which received the signal.
 
-<!-- ##### SIGNAL GtkWindow::activate-focus ##### -->
+<!-- ##### SIGNAL GtkWindow::frame-event ##### -->
 <para>
 
 </para>
 
 @window: the object which received the signal.
+@event: 
+@Returns: 
 
-<!-- ##### SIGNAL GtkWindow::frame-event ##### -->
+<!-- ##### SIGNAL GtkWindow::keys-changed ##### -->
 <para>
 
 </para>
 
 @window: the object which received the signal.
-@event: 
-@Returns: 
 
 <!-- ##### SIGNAL GtkWindow::move-focus ##### -->
 <para>
index 7d5ec04b8f9c75c51ddf390c9de027651eaf065e..8106f813e1837e2c35495722e8c51ea766fc0639 100644 (file)
@@ -52,7 +52,7 @@ static guint           default_accel_mod_mask = (GDK_SHIFT_MASK |
 
 /* --- functions --- */
 /**
- * gtk_accel_map_change_entry
+ * gtk_accel_group_get_type
  * @returns: the type ID for accelerator groups
  */
 GType
@@ -135,6 +135,19 @@ static void
 gtk_accel_group_finalize (GObject *object)
 {
   GtkAccelGroup *accel_group = GTK_ACCEL_GROUP (object);
+  guint i;
+  
+  for (i = 0; i < accel_group->n_accels; i++)
+    {
+      GtkAccelGroupEntry *entry = &accel_group->priv_accels[i];
+
+      if (entry->accel_path_quark)
+       {
+         const gchar *accel_path = g_quark_to_string (entry[i].accel_path_quark);
+
+         _gtk_accel_map_remove_group (accel_path, accel_group);
+       }
+    }
 
   g_free (accel_group->priv_accels);
 
@@ -300,10 +313,12 @@ gtk_accel_group_unlock (GtkAccelGroup *accel_group)
 }
 
 static void
-accel_tag_func (gpointer  data,
-               GClosure *closure)
+accel_closure_invalidate (gpointer  data,
+                         GClosure *closure)
 {
-  /* GtkAccelGroup *accel_group = data; */
+  GtkAccelGroup *accel_group = GTK_ACCEL_GROUP (data);
+
+  gtk_accel_group_disconnect (accel_group, closure);
 }
 
 static int
@@ -330,11 +345,14 @@ quick_accel_add (GtkAccelGroup  *accel_group,
   guint pos, i = accel_group->n_accels++;
   GtkAccelGroupEntry key;
 
+  /* find position */
   key.key.accel_key = accel_key;
   key.key.accel_mods = accel_mods;
   for (pos = 0; pos < i; pos++)
     if (bsearch_compare_accels (&key, accel_group->priv_accels + pos) < 0)
       break;
+
+  /* insert at position, ref closure */
   accel_group->priv_accels = g_renew (GtkAccelGroupEntry, accel_group->priv_accels, accel_group->n_accels);
   g_memmove (accel_group->priv_accels + pos + 1, accel_group->priv_accels + pos,
             (i - pos) * sizeof (accel_group->priv_accels[0]));
@@ -344,9 +362,71 @@ quick_accel_add (GtkAccelGroup  *accel_group,
   accel_group->priv_accels[pos].closure = g_closure_ref (closure);
   accel_group->priv_accels[pos].accel_path_quark = path_quark;
   g_closure_sink (closure);
+  
+  /* handle closure invalidation and reverse lookups */
+  g_closure_add_invalidate_notifier (closure, accel_group, accel_closure_invalidate);
+
+  /* get accel path notification */
+  if (path_quark)
+    _gtk_accel_map_add_group (g_quark_to_string (path_quark), accel_group);
+
+  /* connect and notify changed */
+  if (accel_key)
+    {
+      gchar *accel_name = gtk_accelerator_name (accel_key, accel_mods);
+      GQuark accel_quark = g_quark_from_string (accel_name);
 
-  /* tag closure for backwards lookup */
-  g_closure_add_invalidate_notifier (closure, accel_group, accel_tag_func);
+      g_free (accel_name);
+      
+      /* setup handler */
+      g_signal_connect_closure_by_id (accel_group, signal_accel_activate, accel_quark, closure, FALSE);
+      
+      /* and notify */
+      g_signal_emit (accel_group, signal_accel_changed, accel_quark, accel_key, accel_mods, closure);
+    }
+}
+
+static void
+quick_accel_remove (GtkAccelGroup      *accel_group,
+                   GtkAccelGroupEntry *entry)
+{
+  guint pos = entry - accel_group->priv_accels;
+  GQuark accel_quark = 0;
+  guint accel_key = entry->key.accel_key;
+  GdkModifierType accel_mods = entry->key.accel_mods;
+  GClosure *closure = entry->closure;
+
+  /* quark for notification */
+  if (accel_key)
+    {
+      gchar *accel_name = gtk_accelerator_name (accel_key, accel_mods);
+
+      accel_quark = g_quark_from_string (accel_name);
+      g_free (accel_name);
+    }
+
+  /* clean up closure invalidate notification and disconnect */
+  g_closure_remove_invalidate_notifier (entry->closure, accel_group, accel_closure_invalidate);
+  if (accel_quark)
+    g_signal_handlers_disconnect_matched (accel_group,
+                                         G_SIGNAL_MATCH_ID | G_SIGNAL_MATCH_DETAIL | G_SIGNAL_MATCH_CLOSURE,
+                                         signal_accel_activate, accel_quark,
+                                         closure, NULL, NULL);
+  /* clean up accel path notification */
+  if (entry->accel_path_quark)
+    _gtk_accel_map_remove_group (g_quark_to_string (entry->accel_path_quark), accel_group);
+
+  /* physically remove */
+  accel_group->n_accels -= 1;
+  g_memmove (entry, entry + 1,
+            (accel_group->n_accels - pos) * sizeof (accel_group->priv_accels[0]));
+
+  /* and notify */
+  if (accel_quark)
+    g_signal_emit (accel_group, signal_accel_changed, accel_quark, accel_key, accel_mods, closure);
+
+  /* remove quick_accel_add() refcount */
+  g_closure_unref (closure);
 }
 
 static GtkAccelGroupEntry*
@@ -382,31 +462,6 @@ quick_accel_find (GtkAccelGroup  *accel_group,
   return entry;
 }
 
-static GSList*
-quick_accel_remove (GtkAccelGroup  *accel_group,
-                   guint           accel_key,
-                   GdkModifierType accel_mods)
-{
-  guint i, n;
-  GtkAccelGroupEntry *entry = quick_accel_find (accel_group, accel_key, accel_mods, &n);
-  guint pos = entry - accel_group->priv_accels;
-  GSList *clist = NULL;
-
-  if (!entry)
-    return NULL;
-  for (i = 0; i < n; i++)
-    {
-      g_closure_remove_invalidate_notifier (entry[i].closure, accel_group, accel_tag_func);
-      clist = g_slist_prepend (clist, entry[i].closure);
-    }
-
-  accel_group->n_accels -= n;
-  g_memmove (entry, entry + n,
-            (accel_group->n_accels - pos) * sizeof (accel_group->priv_accels[0]));
-
-  return clist;
-}
-
 /**
  * gtk_accel_group_connect
  * @accel_group:      the ccelerator group to install an accelerator in
@@ -414,90 +469,107 @@ quick_accel_remove (GtkAccelGroup  *accel_group,
  * @accel_mods:       modifier combination of the accelerator
  * @accel_flags:      a flag mask to configure this accelerator
  * @closure:          closure to be executed upon accelerator activation
- * @accel_path_quark: accelerator path quark from GtkAccelMapNotify
  *
  * Install an accelerator in this group. When @accel_group is being activated
  * in response to a call to gtk_accel_groups_activate(), @closure will be
  * invoked if the @accel_key and @accel_mods from gtk_accel_groups_activate()
  * match those of this connection.
  * The signature used for the @closure is that of #GtkAccelGroupActivate.
- * If this connection is made in response to an accelerator path change (see
- * gtk_accel_map_change_entry()) from a #GtkAccelMapNotify notifier,
- * @accel_path_quark must be passed on from the notifier into this function,
- * it should be 0 otherwise.
+ * Note that, due to implementation details, a single closure can only be
+ * connected to one accelerator group.
  */
 void
 gtk_accel_group_connect (GtkAccelGroup *accel_group,
                         guint           accel_key,
                         GdkModifierType accel_mods,
                         GtkAccelFlags   accel_flags,
-                        GClosure       *closure,
-                        GQuark          accel_path_quark)
+                        GClosure       *closure)
 {
-  gchar *accel_name;
-  GQuark accel_quark;
-
   g_return_if_fail (GTK_IS_ACCEL_GROUP (accel_group));
   g_return_if_fail (closure != NULL);
   g_return_if_fail (accel_key > 0);
+  g_return_if_fail (gtk_accel_group_from_accel_closure (closure) == NULL);
 
-  accel_name = gtk_accelerator_name (accel_key, accel_mods);
-  accel_quark = g_quark_from_string (accel_name);
-  g_free (accel_name);
-
-  quick_accel_add (accel_group, accel_key, accel_mods, accel_flags, closure, accel_path_quark);
-
-  /* setup handler */
-  g_signal_connect_closure_by_id (accel_group, signal_accel_activate, accel_quark, closure, FALSE);
-
-  /* and notify */
-  g_signal_emit (accel_group, signal_accel_changed, accel_quark, accel_key, accel_mods, closure);
+  g_object_ref (accel_group);
+  if (!closure->is_invalid)
+    quick_accel_add (accel_group, accel_key, accel_mods, accel_flags, closure, 0);
+  g_object_unref (accel_group);
 }
 
-static gboolean
-accel_group_disconnect_closure (GtkAccelGroup  *accel_group,
-                               guint           accel_key,
-                               GdkModifierType accel_mods,
-                               GClosure       *closure)
+/**
+ * gtk_accel_group_connect_by_path
+ * @accel_group:      the ccelerator group to install an accelerator in
+ * @accel_path:       path used for determining key and modifiers.
+ * @closure:          closure to be executed upon accelerator activation
+ *
+ * Install an accelerator in this group, using a accelerator path to look
+ * up the appropriate key and modifiers. (See gtk_accel_map_add_entry())
+ * When @accel_group is being activated in response to a call to
+ * gtk_accel_groups_activate(), @closure will be invoked if the @accel_key and
+ * @accel_mods from gtk_accel_groups_activate() match the key and modifiers
+ * for the path.
+ * The signature used for the @closure is that of #GtkAccelGroupActivate.
+ */
+void
+gtk_accel_group_connect_by_path (GtkAccelGroup *accel_group,
+                                const gchar    *accel_path,
+                                GClosure       *closure)
 {
-  gchar *accel_name;
-  GQuark accel_quark;
-  GSList *clist , *slist;
-  gboolean removed_some = FALSE;
+  guint accel_key = 0;
+  GdkModifierType accel_mods = 0;
+  GtkAccelKey key;
 
-  accel_name = gtk_accelerator_name (accel_key, accel_mods);
-  accel_quark = g_quark_from_string (accel_name);
-  g_free (accel_name);
+  g_return_if_fail (GTK_IS_ACCEL_GROUP (accel_group));
+  g_return_if_fail (closure != NULL);
+  g_return_if_fail (_gtk_accel_path_is_valid (accel_path));
 
-  clist = quick_accel_remove (accel_group, accel_key, accel_mods);
-  if (!clist)
-    return FALSE;
+  if (closure->is_invalid)
+    return;
 
   g_object_ref (accel_group);
 
-  for (slist = clist; slist; slist = slist->next)
-    if (!closure || slist->data == (gpointer) closure)
-      {
-       g_signal_handlers_disconnect_matched (accel_group, G_SIGNAL_MATCH_CLOSURE | G_SIGNAL_MATCH_ID,
-                                             signal_accel_activate, 0,
-                                             slist->data, NULL, NULL);
-       /* and notify */
-       g_signal_emit (accel_group, signal_accel_changed, accel_quark, accel_key, accel_mods, slist->data);
-       
-       /* remove quick_accel_add() ref_count */
-       g_closure_unref (slist->data);
-
-       removed_some = TRUE;
-      }
-  g_slist_free (clist);
+  if (gtk_accel_map_lookup_entry (accel_path, &key))
+    {
+      accel_key = key.accel_key;
+      accel_mods = key.accel_mods;
+    }
+
+  quick_accel_add (accel_group, accel_key, accel_mods, GTK_ACCEL_VISIBLE, closure,
+                  g_quark_from_string (accel_path));
 
   g_object_unref (accel_group);
-  
-  return removed_some;
 }
 
 /**
  * gtk_accel_group_disconnect
+ * @accel_group: the accelerator group to remove an accelerator from
+ * @closure:     the closure to remove from this accelerator group
+ * @returns:     %TRUE if the closure was found and got disconnected
+ *
+ * Remove an accelerator previously installed through
+ * gtk_accel_group_connect().
+ */
+gboolean
+gtk_accel_group_disconnect (GtkAccelGroup *accel_group,
+                           GClosure      *closure)
+{
+  guint i;
+
+  g_return_val_if_fail (GTK_IS_ACCEL_GROUP (accel_group), FALSE);
+
+  for (i = 0; i < accel_group->n_accels; i++)
+    if (accel_group->priv_accels[i].closure == closure)
+      {
+       g_object_ref (accel_group);
+       quick_accel_remove (accel_group, accel_group->priv_accels + i);
+       g_object_unref (accel_group);
+       return TRUE;
+      }
+  return FALSE;
+}
+
+/**
+ * gtk_accel_group_disconnect_key
  * @accel_group:      the ccelerator group to install an accelerator in
  * @accel_key:        key value of the accelerator
  * @accel_mods:       modifier combination of the accelerator
@@ -507,13 +579,71 @@ accel_group_disconnect_closure (GtkAccelGroup  *accel_group,
  * gtk_accel_group_connect().
  */
 gboolean
-gtk_accel_group_disconnect (GtkAccelGroup  *accel_group,
-                           guint           accel_key,
-                           GdkModifierType accel_mods)
+gtk_accel_group_disconnect_key (GtkAccelGroup  *accel_group,
+                               guint           accel_key,
+                               GdkModifierType accel_mods)
 {
+  GtkAccelGroupEntry *entries;
+  GSList *slist, *clist = NULL;
+  gboolean removed_one = FALSE;
+  guint n;
+
   g_return_val_if_fail (GTK_IS_ACCEL_GROUP (accel_group), FALSE);
 
-  return accel_group_disconnect_closure (accel_group, accel_key, accel_mods, NULL);
+  g_object_ref (accel_group);
+  
+  entries = quick_accel_find (accel_group, accel_key, accel_mods, &n);
+  while (n--)
+    {
+      GClosure *closure = g_closure_ref (entries[n].closure);
+
+      clist = g_slist_prepend (clist, closure);
+    }
+
+  for (slist = clist; slist; slist = slist->next)
+    {
+      GClosure *closure = slist->data;
+
+      removed_one |= gtk_accel_group_disconnect (accel_group, closure);
+      g_closure_unref (closure);
+    }
+  g_slist_free (clist);
+
+  g_object_unref (accel_group);
+
+  return removed_one;
+}
+
+void
+_gtk_accel_group_reconnect (GtkAccelGroup *accel_group,
+                           GQuark         accel_path_quark)
+{
+  GSList *slist, *clist = NULL;
+  guint i;
+
+  g_return_if_fail (GTK_IS_ACCEL_GROUP (accel_group));
+
+  g_object_ref (accel_group);
+
+  for (i = 0; i < accel_group->n_accels; i++)
+    if (accel_group->priv_accels[i].accel_path_quark == accel_path_quark)
+      {
+       GClosure *closure = g_closure_ref (accel_group->priv_accels[i].closure);
+
+       clist = g_slist_prepend (clist, closure);
+      }
+
+  for (slist = clist; slist; slist = slist->next)
+    {
+      GClosure *closure = slist->data;
+
+      gtk_accel_group_disconnect (accel_group, closure);
+      gtk_accel_group_connect_by_path (accel_group, g_quark_to_string (accel_path_quark), closure);
+      g_closure_unref (closure);
+    }
+  g_slist_free (clist);
+
+  g_object_unref (accel_group);
 }
 
 GtkAccelGroupEntry*
@@ -535,38 +665,6 @@ gtk_accel_group_query (GtkAccelGroup  *accel_group,
   return entries;
 }
 
-static gboolean
-find_accel_closure (GtkAccelKey *key,
-                   GClosure    *closure,
-                   gpointer     data)
-{
-  return data == (gpointer) closure;
-}
-
-gboolean
-gtk_accel_groups_disconnect_closure (GClosure *closure)
-{
-  GtkAccelGroup *group;
-
-  g_return_val_if_fail (closure != NULL, FALSE);
-
-  group = gtk_accel_group_from_accel_closure (closure);
-  if (group)
-    {
-      GtkAccelKey *key = gtk_accel_group_find (group, find_accel_closure, closure);
-
-      /* sigh, not finding the key can unexpectedly happen if someone disposes
-       * accel groups. that's highly recommended to _not_ do though.
-       */
-      if (key)
-       {
-         accel_group_disconnect_closure (group, key->accel_key, key->accel_mods, closure);
-         return TRUE;
-       }
-    }
-  return FALSE;
-}
-
 GtkAccelGroup*
 gtk_accel_group_from_accel_closure (GClosure *closure)
 {
@@ -574,15 +672,15 @@ gtk_accel_group_from_accel_closure (GClosure *closure)
 
   g_return_val_if_fail (closure != NULL, NULL);
 
-  /* a few remarks on wat we do here. in general, we need a way to back-lookup
+  /* a few remarks on wat we do here. in general, we need a way to reverse lookup
    * accel_groups from closures that are being used in accel groups. this could
    * be done e.g via a hashtable. it is however cheaper (memory wise) to just
-   * store a NOP notifier on the closure itself that contains the accel group
-   * as data which, besides needing to peek a bit at closure internals, works
-   * just as good.
+   * use the invalidation notifier on the closure itself (which we need to install
+   * anyway), that contains the accel group as data which, besides needing to peek
+   * a bit at closure internals, works just as good.
    */
   for (i = 0; i < G_CLOSURE_N_NOTIFIERS (closure); i++)
-    if (closure->notifiers[i].notify == accel_tag_func)
+    if (closure->notifiers[i].notify == accel_closure_invalidate)
       return closure->notifiers[i].data;
 
   return NULL;
@@ -791,10 +889,10 @@ is_release (const gchar *string)
  * @accelerator_mods: return location for accelerator modifier mask
  *
  * Parses a string representing an accelerator. The
- * format looks like "<Control>a" or "<Shift><Alt>F1" or
- * "<Release>z" (the last one is for key release).
+ * format looks like "&lt;Control&gt;a" or "&lt;Shift&gt;&lt;Alt&gt;F1" or
+ * "&lt;Release&gt;z" (the last one is for key release).
  * The parser is fairly liberal and allows lower or upper case,
- * and also abbreviations such as "<Ctl>" and "<Ctrl>".
+ * and also abbreviations such as "&lt;Ctl&gt;" and "&lt;Ctrl&gt;".
  *
  * If the parse fails, @accelerator_key and @accelerator_mods will
  * be set to 0 (zero).
@@ -911,7 +1009,7 @@ gtk_accelerator_parse (const gchar     *accelerator,
  * Converts an accelerator keyval and modifier mask
  * into a string parseable by gtk_accelerator_parse().
  * For example, if you pass in GDK_q and GDK_CONTROL_MASK,
- * this function returns "<Control>q". 
+ * this function returns "&lt;Control&gt;q". 
  *
  * The caller of this function must free the returned string.
  */
index 5fca1a33b3547f3b22f59fef293b4c2f3561ed02..cfb207f8a7d2e41b38e7524134fd4d56a781c956 100644 (file)
@@ -88,20 +88,23 @@ struct _GtkAccelKey
 
 
 /* -- Accelerator Groups --- */
-GType           gtk_accel_group_get_type        (void);
-GtkAccelGroup*  gtk_accel_group_new            (void);
-void           gtk_accel_group_lock            (GtkAccelGroup  *accel_group);
-void           gtk_accel_group_unlock          (GtkAccelGroup  *accel_group);
-void           gtk_accel_group_connect         (GtkAccelGroup  *accel_group,
-                                                guint           accel_key,
-                                                GdkModifierType accel_mods,
-                                                GtkAccelFlags   accel_flags,
-                                                GClosure       *closure,
-                                                GQuark          accel_path_quark);
-gboolean       gtk_accel_group_disconnect      (GtkAccelGroup  *accel_group,
-                                                guint           accel_key,
-                                                GdkModifierType accel_mods);
-gboolean    gtk_accel_groups_disconnect_closure        (GClosure       *closure);
+GType          gtk_accel_group_get_type           (void);
+GtkAccelGroup* gtk_accel_group_new               (void);
+void          gtk_accel_group_lock               (GtkAccelGroup  *accel_group);
+void          gtk_accel_group_unlock             (GtkAccelGroup  *accel_group);
+void          gtk_accel_group_connect            (GtkAccelGroup  *accel_group,
+                                                  guint           accel_key,
+                                                  GdkModifierType accel_mods,
+                                                  GtkAccelFlags   accel_flags,
+                                                  GClosure       *closure);
+void           gtk_accel_group_connect_by_path    (GtkAccelGroup  *accel_group,
+                                                  const gchar    *accel_path,
+                                                  GClosure       *closure);
+gboolean       gtk_accel_group_disconnect        (GtkAccelGroup  *accel_group,
+                                                  GClosure       *closure);
+gboolean       gtk_accel_group_disconnect_key    (GtkAccelGroup  *accel_group,
+                                                  guint           accel_key,
+                                                  GdkModifierType accel_mods);
 
 
 /* --- GtkActivatable glue --- */
@@ -138,6 +141,10 @@ GtkAccelGroupEntry*        gtk_accel_group_query   (GtkAccelGroup  *accel_group,
                                                 guint           accel_key,
                                                 GdkModifierType accel_mods,
                                                 guint          *n_entries);
+
+void                _gtk_accel_group_reconnect (GtkAccelGroup *accel_group,
+                                                GQuark         accel_path_quark);
+
 struct _GtkAccelGroupEntry
 {
   GtkAccelKey  key;
index efa096fd35e856e43cfb233809aa997f79d6ce1a..b3721e1c4c23f22d3bf06f5bb80b1f79900eb290 100644 (file)
@@ -351,19 +351,21 @@ gtk_accel_label_expose_event (GtkWidget      *widget,
 static void
 refetch_widget_accel_closure (GtkAccelLabel *accel_label)
 {
-  GSList *slist;
-
+  GClosure *closure = NULL;
+  GList *clist, *list;
+  
   g_return_if_fail (GTK_IS_ACCEL_LABEL (accel_label));
   g_return_if_fail (GTK_IS_WIDGET (accel_label->accel_widget));
   
-  for (slist = _gtk_widget_get_accel_closures (accel_label->accel_widget); slist; slist = slist->next)
-    if (gtk_accel_group_from_accel_closure (slist->data))
-      {
-       /* we just take the first correctly used closure */
-       gtk_accel_label_set_accel_closure (accel_label, slist->data);
-       return;
-      }
-  gtk_accel_label_set_accel_closure (accel_label, NULL);
+  clist = gtk_widget_list_accel_closures (accel_label->accel_widget);
+  for (list = clist; list; list = list->next)
+    {
+      /* we just take the first closure used */
+      closure = list->data;
+      break;
+    }
+  g_list_free (clist);
+  gtk_accel_label_set_accel_closure (accel_label, closure);
 }
 
 void
index d99e01aacb3dfd3568c161513ad50a485258af1f..7fe375c606e9574b08367c86a85bd869ac260aa9 100644 (file)
@@ -42,7 +42,7 @@ typedef struct {
   guint               std_accel_key;
   guint               std_accel_mods;
   guint        changed : 1;
-  GHookList   *hooks;
+  GSList      *groups;
 } AccelEntry;
 
 
@@ -89,8 +89,8 @@ _gtk_accel_map_init (void)
   accel_entry_ht = g_hash_table_new (accel_entry_hash, accel_entry_equal);
 }
 
-static gboolean
-gtk_accel_path_is_valid (const gchar *accel_path)
+gboolean
+_gtk_accel_path_is_valid (const gchar *accel_path)
 {
   gchar *p;
 
@@ -108,14 +108,13 @@ gtk_accel_path_is_valid (const gchar *accel_path)
  * @accel_path: valid accelerator path
  * @accel_key:  the accelerator key
  * @accel_mods: the accelerator modifiers
- * @returns:    the GQuark for the @accel_path (to ease local storage)
  *
  * Register a new accelerator with the global accelerator map.
  * This function should only be called once per @accel_path
  * with the canonical @accel_key and @accel_mods for this path.
  * To change the accelerator during runtime programatically, use
  * gtk_accel_map_change_entry().
- * The accelerator path must consist of "<WINDOWTYPE>/Category1/Category2/.../Action",
+ * The accelerator path must consist of "&lt;WINDOWTYPE&gt;/Category1/Category2/.../Action",
  * where WINDOWTYPE should be a unique application specifc identifier, that
  * corresponds to the kind of window the accelerator is being used in, e.g. "Gimp-Image",
  * "Abiword-Document" or "Gnumeric-Settings".
@@ -123,18 +122,21 @@ gtk_accel_path_is_valid (const gchar *accel_path)
  * accelerator triggers, i.e. for accelerators on menu items, choose the item's menu path,
  * e.g. "File/Save As", "Image/View/Zoom" or "Edit/Select All".
  * So a full valid accelerator path may look like:
- * "<Gimp-Toolbox>/File/Dialogs/Tool Options...".
+ * "&lt;Gimp-Toolbox&gt;/File/Dialogs/Tool Options...".
  */
-GQuark
+void
 gtk_accel_map_add_entry (const gchar *accel_path,
                         guint        accel_key,
                         guint        accel_mods)
 {
   AccelEntry *entry;
 
-  g_return_val_if_fail (gtk_accel_path_is_valid (accel_path), 0);
+  g_return_if_fail (_gtk_accel_path_is_valid (accel_path));
 
-  accel_mods &= gtk_accelerator_get_default_mod_mask ();
+  if (!accel_key)
+    accel_mods = 0;
+  else
+    accel_mods &= gtk_accelerator_get_default_mod_mask ();
 
   entry = accel_path_lookup (accel_path);
   if (entry)
@@ -159,154 +161,35 @@ gtk_accel_map_add_entry (const gchar *accel_path,
       entry->changed = FALSE;
       g_hash_table_insert (accel_entry_ht, entry, entry);
     }
-  return g_quark_try_string (entry->accel_path);
-}
-
-typedef struct {
-  GHook          hook;
-  GtkAccelGroup *accel_group;
-} AccelHook;
-
-static void
-accel_hook_finalize (GHookList *hook_list,
-                    GHook     *hook)
-{
-  GDestroyNotify destroy = hook->destroy;
-  AccelHook *ahook = (AccelHook*) hook;
-
-  if (ahook->accel_group)
-    g_object_unref (ahook->accel_group);
-
-  if (destroy)
-    {
-      hook->destroy = NULL;
-      destroy (hook->data);
-    }
-}
-
-/**
- * GtkAccelMapNotify
- * @data:             notifier user data
- * @accel_path_quark: accelerator path (as #GQuark) which has just changed
- * @accel_key:        new accelerator key
- * @accel_mods:       new accelerator modifiers
- * @accel_group:      accelerator group of this notifier
- * @old_accel_key:    former accelerator key
- * @old_accel_mods):  former accelerator modifiers
- *
- * #GtkAccelMapNotify is the signature of user callbacks, installed via
- * gtk_accel_map_add_notifier(). Once the accel path of the notifier changes,
- * the notifier is invoked with this signature, where @accel_path_quark
- * indicates the accel path that changed, and @data and @accel_group are
- * the notifier's arguments as passed into gtk_accel_map_add_notifier().
- */
-
-/**
- * gtk_accel_map_add_notifer
- * @accel_path:  valid accelerator path
- * @notify_data: data argument to the notifier
- * @notify_func: the notifier function
- * @accel_group: accelerator group used by the notifier function
- *
- * Install a notifier function to be called if an accelerator
- * map entry changes. @accel_group has to be the accel group
- * that is being affected (gets an accelerator removed or added,
- * when the notifier function is executed).
- */
-void
-gtk_accel_map_add_notifer (const gchar      *accel_path,
-                          gpointer          notify_data,
-                          GtkAccelMapNotify notify_func,
-                          GtkAccelGroup    *accel_group)
-{
-  AccelEntry *entry;
-  AccelHook *ahook;
-  GHook *hook;
-
-  g_return_if_fail (gtk_accel_path_is_valid (accel_path));
-  g_return_if_fail (notify_func != NULL);
-  if (accel_group)
-    g_return_if_fail (GTK_IS_ACCEL_GROUP (accel_group));
-
-  entry = accel_path_lookup (accel_path);
-  if (!entry)
-    {
-      gtk_accel_map_add_entry (accel_path, 0, 0);
-      entry = accel_path_lookup (accel_path);
-    }
-  if (!entry->hooks)
-    {
-      entry->hooks = g_new (GHookList, 1);
-      g_hook_list_init (entry->hooks, sizeof (AccelHook));
-      entry->hooks->finalize_hook = accel_hook_finalize;
-    }
-  hook = g_hook_alloc (entry->hooks);
-  hook->data = notify_data;
-  hook->func = notify_func;
-  hook->destroy = NULL;
-  ahook = (AccelHook*) hook;
-  ahook->accel_group = accel_group ? g_object_ref (accel_group) : NULL;
-  g_hook_append (entry->hooks, hook);
-}
-
-/**
- * gtk_accel_map_remove_notifer
- * @accel_path:  valid accelerator path
- * @notify_data: data argument to the notifier
- * @notify_func: the notifier function
- *
- * Remove a notifier function, previously installed through
- * gtk_accel_map_add_notifer().
- */
-void
-gtk_accel_map_remove_notifer (const gchar      *accel_path,
-                             gpointer          notify_data,
-                             GtkAccelMapNotify notify_func)
-{
-  AccelEntry *entry;
-
-  g_return_if_fail (gtk_accel_path_is_valid (accel_path));
-  g_return_if_fail (notify_func != NULL);
-
-  entry = accel_path_lookup (accel_path);
-  if (entry && entry->hooks)
-    {
-      GHook *hook = g_hook_find_func_data (entry->hooks, TRUE, notify_func, notify_data);
-
-      if (hook && g_hook_destroy (entry->hooks, hook->hook_id))
-       return; /* successfully removed */
-    }
-  g_warning (G_STRLOC ": no notifier %p(%p) installed for accel path \"%s\"",
-            notify_func, notify_data, accel_path);
 }
 
 /**
  * gtk_accel_map_lookup_entry
  * @accel_path:  valid accelerator path
  * @key:         accelerator key to be filled in (optional)
- * @returns:     #GQuark for @accel_path or (0) if @accel_path is not known
+ * @returns:     %TRUE if @accel_path is known, %FALSE otherwise
  *
  * Lookup the accelerator entry for @accel_path and fill in @key.
  * If the lookup revealed no results, (0) is returned, the entry's
  * #GQuark otherwise.
  */
-GQuark
+gboolean
 gtk_accel_map_lookup_entry (const gchar *accel_path,
                            GtkAccelKey *key)
 {
   AccelEntry *entry;
 
-  g_return_val_if_fail (gtk_accel_path_is_valid (accel_path), 0);
+  g_return_val_if_fail (_gtk_accel_path_is_valid (accel_path), FALSE);
 
   entry = accel_path_lookup (accel_path);
   if (entry && key)
     {
       key->accel_key = entry->accel_key;
       key->accel_mods = entry->accel_mods;
-      key->accel_flags = 0;    // FIXME: global lock?
+      key->accel_flags = 0;
     }
 
-  return entry ? g_quark_try_string (entry->accel_path) : 0;
+  return entry ? TRUE : FALSE;
 }
 
 static void
@@ -340,9 +223,8 @@ internal_change_entry (const gchar    *accel_path,
 {
   GSList *node, *slist, *win_list, *group_list, *replace_list = NULL;
   GHashTable *group_hm, *win_hm;
-  gboolean change_accel, removable, can_change = TRUE, seen_accel = FALSE, hooks_may_recurse = TRUE;
+  gboolean change_accel, removable, can_change = TRUE, seen_accel = FALSE;
   GQuark entry_quark;
-  GHook *hook;
   AccelEntry *entry = accel_path_lookup (accel_path);
 
   /* not much todo if there's no entry yet */
@@ -364,7 +246,7 @@ internal_change_entry (const gchar    *accel_path,
     return FALSE;
 
   /* nobody's interested, easy going */
-  if (!entry->hooks)
+  if (!entry->groups)
     {
       if (!simulate)
        {
@@ -379,15 +261,8 @@ internal_change_entry (const gchar    *accel_path,
   entry_quark = g_quark_try_string (entry->accel_path);
   group_hm = g_hash_table_new (NULL, NULL);
   win_hm = g_hash_table_new (NULL, NULL);
-  hook = g_hook_first_valid (entry->hooks, hooks_may_recurse);
-  while (hook)
-    {
-      AccelHook *ahook = (AccelHook*) hook;
-      
-      if (ahook->accel_group)
-       g_hash_table_insert (group_hm, ahook->accel_group, ahook->accel_group);
-      hook = g_hook_next_valid (entry->hooks, hook, hooks_may_recurse);
-    }
+  for (slist = entry->groups; slist; slist = slist->next)
+    g_hash_table_insert (group_hm, slist->data, slist->data);
 
   /* 2) collect acceleratables affected */
   group_list = g_hash_table_slist_values (group_hm);
@@ -408,62 +283,69 @@ internal_change_entry (const gchar    *accel_path,
       g_hash_table_insert (group_hm, node->data, node->data);
   group_list = g_hash_table_slist_values (group_hm);
   g_hash_table_destroy (group_hm);
-
+  
   /* 4) walk the acceleratables and figure whether they occupy accel_key&accel_mods */
-  for (slist = accel_key ? win_list : NULL; slist; slist = slist->next)
-    if (GTK_IS_WINDOW (slist->data))   /* bad kludge in lack of a GtkAcceleratable */
-      if (_gtk_window_query_nonaccels (slist->data, accel_key, accel_mods))
-       {
-         seen_accel = TRUE;
-         break;
-       }
+  if (accel_key)
+    for (slist = win_list; slist; slist = slist->next)
+      if (GTK_IS_WINDOW (slist->data)) /* bad kludge in lack of a GtkAcceleratable */
+       if (_gtk_window_query_nonaccels (slist->data, accel_key, accel_mods))
+         {
+           seen_accel = TRUE;
+           break;
+         }
   removable = !seen_accel;
-
+  
   /* 5) walk all accel groups and search for locks */
-  for (slist = removable ? group_list : NULL; slist; slist = slist->next)
-    {
-      GtkAccelGroup *group = slist->data;
-      GtkAccelGroupEntry *ag_entry;
-      guint i, n;
-      
-      n = 0;
-      ag_entry = entry->accel_key ? gtk_accel_group_query (group, entry->accel_key, entry->accel_mods, &n) : NULL;
-      for (i = 0; i < n; i++)
-       if (ag_entry[i].accel_path_quark == entry_quark)
+  if (removable)
+    for (slist = group_list; slist; slist = slist->next)
+      {
+       GtkAccelGroup *group = slist->data;
+       GtkAccelGroupEntry *ag_entry;
+       guint i, n;
+       
+       n = 0;
+       ag_entry = entry->accel_key ? gtk_accel_group_query (group, entry->accel_key, entry->accel_mods, &n) : NULL;
+       for (i = 0; i < n; i++)
+         if (ag_entry[i].accel_path_quark == entry_quark)
+           {
+             can_change = !(ag_entry[i].key.accel_flags & GTK_ACCEL_LOCKED);
+             if (!can_change)
+               goto break_loop_step5;
+           }
+       
+       n = 0;
+       ag_entry = accel_key ? gtk_accel_group_query (group, accel_key, accel_mods, &n) : NULL;
+       for (i = 0; i < n; i++)
          {
-           can_change = !(ag_entry[i].key.accel_flags & GTK_ACCEL_LOCKED);
-           if (!can_change)
+           seen_accel = TRUE;
+           removable = !group->lock_count && !(ag_entry[i].key.accel_flags & GTK_ACCEL_LOCKED);
+           if (!removable)
              goto break_loop_step5;
+           if (ag_entry[i].accel_path_quark)
+             replace_list = g_slist_prepend (replace_list, GUINT_TO_POINTER (ag_entry->accel_path_quark));
          }
-
-      n = 0;
-      ag_entry = accel_key ? gtk_accel_group_query (group, accel_key, accel_mods, &n) : NULL;
-      for (i = 0; i < n; i++)
-       {
-         seen_accel = TRUE;
-         removable = !group->lock_count && !(ag_entry[i].key.accel_flags & GTK_ACCEL_LOCKED);
-         if (!removable)
-           goto break_loop_step5;
-         if (ag_entry[i].accel_path_quark)
-           replace_list = g_slist_prepend (replace_list, GUINT_TO_POINTER (ag_entry->accel_path_quark));
-       }
-    }
+      }
  break_loop_step5:
   
   /* 6) check whether we can remove existing accelerators */
-  for (slist = removable ? replace_list : NULL; slist; slist = slist->next)
-    if (!internal_change_entry (g_quark_to_string (GPOINTER_TO_UINT (slist->data)), 0, 0, FALSE, TRUE))
-      {
-       removable = FALSE;
-       break;
-      }
-
+  if (removable && can_change)
+    for (slist = replace_list; slist; slist = slist->next)
+      if (!internal_change_entry (g_quark_to_string (GPOINTER_TO_UINT (slist->data)), 0, 0, FALSE, TRUE))
+       {
+         removable = FALSE;
+         break;
+       }
+  
   /* 7) check conditions and proceed if possible */
   change_accel = can_change && (!seen_accel || (removable && replace));
-
+  
   if (change_accel && !simulate)
     {
       guint old_accel_key, old_accel_mods;
+      
+      /* ref accel groups */
+      for (slist = group_list; slist; slist = slist->next)
+       g_object_ref (slist->data);
 
       /* 8) remove existing accelerators */
       for (slist = replace_list; slist; slist = slist->next)
@@ -475,25 +357,12 @@ internal_change_entry (const gchar    *accel_path,
       entry->accel_key = accel_key;
       entry->accel_mods = accel_mods;
       entry->changed = TRUE;
-      hook = g_hook_first_valid (entry->hooks, hooks_may_recurse);
-      while (hook)
-       {
-         gboolean was_in_call, need_destroy = FALSE;
-         GtkAccelMapNotify hook_func = hook->func;
-         AccelHook *ahook = (AccelHook*) hook;
-         
-         was_in_call = G_HOOK_IN_CALL (hook);
-         hook->flags |= G_HOOK_FLAG_IN_CALL;
-         /* need_destroy = */ hook_func (hook->data, g_quark_try_string (entry->accel_path),
-                                         entry->accel_key, entry->accel_mods,
-                                         ahook->accel_group,
-                                         old_accel_key, old_accel_mods);
-         if (!was_in_call)
-           hook->flags &= ~G_HOOK_FLAG_IN_CALL;
-         if (need_destroy)
-           g_hook_destroy_link (entry->hooks, hook);
-         hook = g_hook_next_valid (entry->hooks, hook, hooks_may_recurse);
-       }
+      for (slist = group_list; slist; slist = slist->next)
+       _gtk_accel_group_reconnect (slist->data, g_quark_from_string (entry->accel_path));
+
+      /* unref accel groups */
+      for (slist = group_list; slist; slist = slist->next)
+       g_object_unref (slist->data);
     }
   g_slist_free (replace_list);
   g_slist_free (group_list);
@@ -513,12 +382,9 @@ internal_change_entry (const gchar    *accel_path,
  * Change the @accel_key and @accel_mods currently associated with @accel_path.
  * Due to conflicts with other accelerators, a change may not alwys be possible,
  * @replace indicates whether other accelerators may be deleted to resolve such
- * conflicts. A change will only occour if all conflicts could be resolved (which
- * might not be the case if conflicting accelerators are locked). Succesfull
+ * conflicts. A change will only occur if all conflicts could be resolved (which
+ * might not be the case if conflicting accelerators are locked). Succesful
  * changes are indicated by a %TRUE return value.
- * Changes occouring are also indicated by invocation of notifiers attached to
- * @accel_path (see gtk_accel_map_add_notifer() on this) and other accelerators
- * that are being deleted.
  */
 gboolean
 gtk_accel_map_change_entry (const gchar    *accel_path,
@@ -526,7 +392,7 @@ gtk_accel_map_change_entry (const gchar    *accel_path,
                            GdkModifierType accel_mods,
                            gboolean        replace)
 {
-  g_return_val_if_fail (gtk_accel_path_is_valid (accel_path), FALSE);
+  g_return_val_if_fail (_gtk_accel_path_is_valid (accel_path), FALSE);
 
   return internal_change_entry (accel_path, accel_key, accel_key ? accel_mods : 0, replace, FALSE);
 }
@@ -865,3 +731,34 @@ gtk_accel_map_add_filter (const gchar *filter_pattern)
       }
   accel_filters = g_slist_prepend (accel_filters, pspec);
 }
+
+void
+_gtk_accel_map_add_group (const gchar   *accel_path,
+                         GtkAccelGroup *accel_group)
+{
+  AccelEntry *entry;
+
+  g_return_if_fail (_gtk_accel_path_is_valid (accel_path));
+  g_return_if_fail (GTK_IS_ACCEL_GROUP (accel_group));
+
+  entry = accel_path_lookup (accel_path);
+  if (!entry)
+    {
+      gtk_accel_map_add_entry (accel_path, 0, 0);
+      entry = accel_path_lookup (accel_path);
+    }
+  entry->groups = g_slist_prepend (entry->groups, accel_group);
+}
+
+void
+_gtk_accel_map_remove_group (const gchar   *accel_path,
+                            GtkAccelGroup *accel_group)
+{
+  AccelEntry *entry;
+
+  entry = accel_path_lookup (accel_path);
+  g_return_if_fail (entry != NULL);
+  g_return_if_fail (g_slist_find (entry->groups, accel_group));
+
+  entry->groups = g_slist_remove (entry->groups, accel_group);
+}
index 99d0887ff338f91573d1381a336a7a3134629759..7a59b2d808079a7e0ed3277bcc32f490b9bc9b3d 100644 (file)
@@ -26,13 +26,6 @@ G_BEGIN_DECLS
 
 
 /* --- notifier --- */
-typedef void (*GtkAccelMapNotify)              (gpointer        data,
-                                                GQuark          accel_path_quark,
-                                                guint           accel_key,
-                                                guint           accel_mods,
-                                                GtkAccelGroup  *accel_group,
-                                                guint           old_accel_key,
-                                                guint           old_accel_mods);
 typedef void (*GtkAccelMapForeach)             (gpointer        data,
                                                 const gchar    *accel_path,
                                                 guint           accel_key,
@@ -41,17 +34,10 @@ typedef void (*GtkAccelMapForeach)          (gpointer        data,
 
 
 /* --- public API --- */
-GQuark    gtk_accel_map_add_entry      (const gchar            *accel_path,
+void      gtk_accel_map_add_entry      (const gchar            *accel_path,
                                         guint                   accel_key,
                                         guint                   accel_mods);
-void      gtk_accel_map_add_notifer    (const gchar            *accel_path,
-                                        gpointer                notify_data,
-                                        GtkAccelMapNotify       notify_func,
-                                        GtkAccelGroup          *accel_group);
-void      gtk_accel_map_remove_notifer (const gchar            *accel_path,
-                                        gpointer                notify_data,
-                                        GtkAccelMapNotify       notify_func);
-GQuark     gtk_accel_map_lookup_entry  (const gchar            *accel_path,
+gboolean   gtk_accel_map_lookup_entry  (const gchar            *accel_path,
                                         GtkAccelKey            *key);
 gboolean   gtk_accel_map_change_entry  (const gchar            *accel_path,
                                         guint                   accel_key,
@@ -75,6 +61,12 @@ void gtk_accel_map_foreach_unfilterd (gpointer                data,
 /* --- internal API --- */
 void           _gtk_accel_map_init             (void);
 
+void            _gtk_accel_map_add_group        (const gchar   *accel_path,
+                                                 GtkAccelGroup *accel_group);
+void            _gtk_accel_map_remove_group     (const gchar   *accel_path,
+                                                 GtkAccelGroup *accel_group);
+gboolean       _gtk_accel_path_is_valid         (const gchar   *accel_path);
+
 
 G_END_DECLS
 
index 02fa3df2e6b92232d9ac84c7eec8a1ca99d602fe..a97abae70d8bae1847f08ee9c3c17f7ee4c851da 100644 (file)
@@ -293,7 +293,7 @@ gtk_item_factory_add_foreign (GtkWidget      *accel_widget,
    */
   if (gtk_signal_lookup ("activate", GTK_OBJECT_TYPE (accel_widget)))
     {
-      if (accel_key && accel_group)
+      if (accel_group)
        {
          gtk_accel_map_add_entry (full_path, accel_key, accel_mods);
          _gtk_widget_set_accel_path (accel_widget, full_path, accel_group);
index 375b348c40c26536409c3e6db82a0367f9363637..7a066aef4ff1dadee64b86159dd985dce38afdcf 100644 (file)
@@ -133,6 +133,9 @@ static void gtk_menu_reparent       (GtkMenu           *menu,
 static void gtk_menu_remove         (GtkContainer      *menu,
                                     GtkWidget         *widget);
 
+static void _gtk_menu_refresh_accel_paths (GtkMenu *menu,
+                                          gboolean group_changed);
+
 static GtkMenuShellClass *parent_class = NULL;
 static const gchar      *attach_data_key = "gtk-menu-attach-data";
 
@@ -866,8 +869,8 @@ gtk_menu_get_accel_group (GtkMenu *menu)
  * each menu item of this menu, that contains a label describing its purpose,
  * automatically gets an accel path assigned. For example, a menu containing
  * menu items "New" and "Exit", will, after gtk_menu_set_accel_path (menu,
- * "<Gnumeric-Sheet>/File"); has been called, assign its items the accel paths:
- * "<Gnumeric-Sheet>/File/New" and "<Gnumeric-Sheet>/File/Exit".
+ * "&lt;Gnumeric-Sheet&gt;/File"); has been called, assign its items the accel paths:
+ * "&lt;Gnumeric-Sheet&gt;/File/New" and "&lt;Gnumeric-Sheet&gt;/File/Exit".
  * Assigning accel paths to menu items then enables the user to change
  * their accelerators at runtime. More details about accelerator paths
  * and their default setups can be found at gtk_accel_map_add_entry().
@@ -892,7 +895,7 @@ typedef struct {
 } AccelPropagation;
 
 static void
-refresh_accel_paths_froeach (GtkWidget *widget,
+refresh_accel_paths_foreach (GtkWidget *widget,
                             gpointer   data)
 {
   AccelPropagation *prop = data;
@@ -904,7 +907,7 @@ refresh_accel_paths_froeach (GtkWidget *widget,
                                       prop->group_changed);
 }
 
-void
+static void
 _gtk_menu_refresh_accel_paths (GtkMenu *menu,
                               gboolean group_changed)
 {
@@ -917,7 +920,7 @@ _gtk_menu_refresh_accel_paths (GtkMenu *menu,
       prop.menu = menu;
       prop.group_changed = group_changed;
       gtk_container_foreach (GTK_CONTAINER (menu),
-                            refresh_accel_paths_froeach,
+                            refresh_accel_paths_foreach,
                             &prop);
     }
 }
index 225c9a90b2babf553f0380689a17962dee099ff0..cdd858a840e92050de0dcf7c4bd9060e40abd743 100644 (file)
@@ -149,8 +149,6 @@ void               gtk_menu_set_accel_group   (GtkMenu             *menu,
 GtkAccelGroup* gtk_menu_get_accel_group          (GtkMenu             *menu);
 void           gtk_menu_set_accel_path    (GtkMenu             *menu,
                                           const gchar         *accel_path);
-void       _gtk_menu_refresh_accel_paths (GtkMenu             *menu,
-                                          gboolean             group_changed);
 
 /* A reference count is kept for a widget when it is attached to
  * a particular widget. This is typically a menu item; it may also
index b65e0d68fe65c7903364270305314e2fd5f6284f..bb64921cf3b269dfa7ec1c73caddc7e8bc2e68ff 100644 (file)
@@ -2615,6 +2615,8 @@ gtk_widget_add_accelerator (GtkWidget     *widget,
 
   closure = widget_new_accel_closure (widget, query.signal_id);
 
+  g_object_ref (widget);
+
   /* install the accelerator. since we don't map this onto an accel_path,
    * the accelerator will automatically be locked.
    */
@@ -2622,10 +2624,11 @@ gtk_widget_add_accelerator (GtkWidget     *widget,
                           accel_key,
                           accel_mods,
                           accel_flags | GTK_ACCEL_LOCKED,
-                          closure,
-                          0);
+                          closure);
 
   g_signal_emit (widget, widget_signals[ACCEL_CLOSURES_CHANGED], 0);
+
+  g_object_unref (widget);
 }
 
 /**
@@ -2646,24 +2649,31 @@ gtk_widget_remove_accelerator (GtkWidget     *widget,
                               guint          accel_mods)
 {
   GtkAccelGroupEntry *ag_entry;
-  GSList *slist;
-  guint n, i;
+  GList *slist, *clist;
+  guint n;
   
   g_return_val_if_fail (GTK_IS_WIDGET (widget), FALSE);
   g_return_val_if_fail (GTK_IS_ACCEL_GROUP (accel_group), FALSE);
 
   ag_entry = gtk_accel_group_query (accel_group, accel_key, accel_mods, &n);
-  for (slist = _gtk_widget_get_accel_closures (widget); slist; slist = slist->next)
+  clist = gtk_widget_list_accel_closures (widget);
+  for (slist = clist; slist; slist = slist->next)
     {
-      /* paranoid sanity checking */
+      guint i;
+
       for (i = 0; i < n; i++)
        if (slist->data == (gpointer) ag_entry[i].closure)
          {
-           gboolean is_removed = gtk_accel_groups_disconnect_closure (slist->data);
+           gboolean is_removed = gtk_accel_group_disconnect (accel_group, slist->data);
+
            g_signal_emit (widget, widget_signals[ACCEL_CLOSURES_CHANGED], 0);
+
+           g_list_free (clist);
+
            return is_removed;
          }
     }
+  g_list_free (clist);
 
   g_warning (G_STRLOC ": no accelerator (%u,%u) installed in accel group (%p) for %s (%p)",
             accel_key, accel_mods, accel_group,
@@ -2672,73 +2682,48 @@ gtk_widget_remove_accelerator (GtkWidget     *widget,
   return FALSE;
 }
 
-GSList*
-_gtk_widget_get_accel_closures (GtkWidget *widget)
+/**
+ * gtk_widget_list_accel_closures
+ * @widget:  widget to list accelerator closures for
+ * @returns: a newly allocated #GList of closures
+ *
+ * List the closures used by @widget for accelerator group connections
+ * with gtk_accel_group_connect_by_path() or gtk_accel_group_connect().
+ * The closures can be used to monitor accelerator changes on @widget,
+ * by connecting to the ::accel_changed signal of the #GtkAccelGroup
+ * of a closure which can be found out with gtk_accel_group_from_accel_closure().
+ */
+GList*
+gtk_widget_list_accel_closures (GtkWidget *widget)
 {
+  GSList *slist;
+  GList *clist = NULL;
+
   g_return_val_if_fail (GTK_IS_WIDGET (widget), NULL);
 
-  return g_object_get_qdata (G_OBJECT (widget), quark_accel_closures);
+  for (slist = g_object_get_qdata (G_OBJECT (widget), quark_accel_closures); slist; slist = slist->next)
+    if (gtk_accel_group_from_accel_closure (slist->data))
+      clist = g_list_prepend (clist, slist->data);
+  return clist;
 }
 
 typedef struct {
+  GQuark         path_quark;
   GtkWidget     *widget;
   GtkAccelGroup *accel_group;
-  const gchar   *path;
   GClosure      *closure;
 } AccelPath;
 
-static void
-accel_path_changed (gpointer        data,
-                   GQuark          accel_path_quark,
-                   guint           accel_key,
-                   guint           accel_mods,
-                   GtkAccelGroup  *accel_group,
-                   guint           old_accel_key,
-                   guint           old_accel_mods)
-{
-  AccelPath *apath = data;
-  gboolean notify = FALSE;
-  
-  if (apath->closure)
-    {
-      /* the closure might have been removed already (due to replacements) */
-      gtk_accel_groups_disconnect_closure (apath->closure);
-      g_closure_unref (apath->closure);
-      apath->closure = NULL;
-      notify = TRUE;
-    }
-  if (accel_key)
-    {
-      apath->closure = widget_new_accel_closure (apath->widget, GTK_WIDGET_GET_CLASS (apath->widget)->activate_signal);
-      g_closure_ref (apath->closure);
-      /* need to specify path to get an unlocked accelerator */
-      gtk_accel_group_connect (apath->accel_group,
-                              accel_key,
-                              accel_mods,
-                              GTK_ACCEL_VISIBLE,
-                              apath->closure,
-                              accel_path_quark);
-      notify = TRUE;
-    }
-  if (notify)
-    g_signal_emit (apath->widget, widget_signals[ACCEL_CLOSURES_CHANGED], 0);
-}
-
 static void
 destroy_accel_path (gpointer data)
 {
   AccelPath *apath = data;
 
-  /* stop notification */
-  gtk_accel_map_remove_notifer (apath->path, apath, accel_path_changed);
+  gtk_accel_group_disconnect (apath->accel_group, apath->closure);
 
-  /* if the closure is currently connected, get rid of that connection */
-  if (apath->closure)
-    {
-      gtk_accel_groups_disconnect_closure (apath->closure);
-      g_closure_unref (apath->closure);
-    }
+  /* closures_destroy takes care of unrefing the closure */
   g_object_unref (apath->accel_group);
+  
   g_free (apath);
 }
 
@@ -2753,25 +2738,21 @@ _gtk_widget_set_accel_path (GtkWidget     *widget,
                            GtkAccelGroup *accel_group)
 {
   AccelPath *apath;
-  GtkAccelKey key;
 
   g_return_if_fail (GTK_IS_WIDGET (widget));
   g_return_if_fail (GTK_WIDGET_GET_CLASS (widget)->activate_signal != 0);
-  if (accel_path)
-    g_return_if_fail (GTK_IS_ACCEL_GROUP (accel_group));
 
   if (accel_path)
     {
-      GQuark quark_path = gtk_accel_map_add_entry (accel_path, 0, 0);
-
-      if (!quark_path)
-       return;         /* pathologic anyway */
+      g_return_if_fail (GTK_IS_ACCEL_GROUP (accel_group));
+      g_return_if_fail (_gtk_accel_path_is_valid (accel_path));
 
+      gtk_accel_map_add_entry (accel_path, 0, 0);
       apath = g_new (AccelPath, 1);
       apath->widget = widget;
       apath->accel_group = g_object_ref (accel_group);
-      apath->path = g_quark_to_string (quark_path);
-      apath->closure = NULL;
+      apath->path_quark = g_quark_from_string (accel_path);
+      apath->closure = widget_new_accel_closure (apath->widget, GTK_WIDGET_GET_CLASS (apath->widget)->activate_signal);
     }
   else
     apath = NULL;
@@ -2780,14 +2761,9 @@ _gtk_widget_set_accel_path (GtkWidget     *widget,
   g_object_set_qdata_full (G_OBJECT (widget), quark_accel_path, apath, destroy_accel_path);
 
   if (apath)
-    {
-      /* setup accel path hooks to react to changes */
-      gtk_accel_map_add_notifer (apath->path, apath, accel_path_changed, apath->accel_group);
+    gtk_accel_group_connect_by_path (apath->accel_group, g_quark_to_string (apath->path_quark), apath->closure);
 
-      /* install accelerators for this path */
-      if (gtk_accel_map_lookup_entry (apath->path, &key))
-       accel_path_changed (apath, g_quark_try_string (apath->path), key.accel_key, key.accel_mods, NULL, 0, 0);
-    }
+  g_signal_emit (widget, widget_signals[ACCEL_CLOSURES_CHANGED], 0);
 }
 
 const gchar*
@@ -2798,7 +2774,7 @@ _gtk_widget_get_accel_path (GtkWidget *widget)
   g_return_val_if_fail (GTK_IS_WIDGET (widget), NULL);
 
   apath = g_object_get_qdata (G_OBJECT (widget), quark_accel_path);
-  return apath ? apath->path : NULL;
+  return apath ? g_quark_to_string (apath->path_quark) : NULL;
 }
 
 gboolean
index ee464fa436bbe268ee2f3a3e84401448c650a1ba..08940458b05e146d2c1543f6ff68982469fdcffc 100644 (file)
@@ -492,7 +492,7 @@ void         _gtk_widget_set_accel_path   (GtkWidget           *widget,
                                           const gchar         *accel_path,
                                           GtkAccelGroup       *accel_group);
 const gchar* _gtk_widget_get_accel_path   (GtkWidget           *widget);
-GSList*    _gtk_widget_get_accel_closures (GtkWidget          *widget);
+GList*     gtk_widget_list_accel_closures (GtkWidget          *widget);
 gboolean   gtk_widget_mnemonic_activate   (GtkWidget           *widget,
                                           gboolean             group_cycling);
 gboolean   gtk_widget_event              (GtkWidget           *widget,
index 27c5eed10dfa9641ca4d22431f63f02979e022af..1039a577ea2e332438f0b76468ad8183f58766c5 100644 (file)
@@ -46,7 +46,7 @@ enum {
   ACTIVATE_FOCUS,
   ACTIVATE_DEFAULT,
   MOVE_FOCUS,
-  ACCELS_CHANGED,
+  KEYS_CHANGED,
   LAST_SIGNAL
 };
 
@@ -222,7 +222,7 @@ static void     gtk_window_set_default_size_internal (GtkWindow    *window,
 
 static void     gtk_window_realize_icon               (GtkWindow    *window);
 static void     gtk_window_unrealize_icon             (GtkWindow    *window);
-static void    gtk_window_notify_accels_changed      (GtkWindow    *window);
+static void    gtk_window_notify_keys_changed      (GtkWindow    *window);
 
 static GSList      *toplevel_list = NULL;
 static GHashTable  *mnemonic_hash_table = NULL;
@@ -350,7 +350,7 @@ gtk_window_class_init (GtkWindowClass *klass)
   klass->activate_default = gtk_window_real_activate_default;
   klass->activate_focus = gtk_window_real_activate_focus;
   klass->move_focus = gtk_window_move_focus;
-  klass->accels_changed = NULL;
+  klass->keys_changed = NULL;
   
   /* Construct */
   g_object_class_install_property (gobject_class,
@@ -500,11 +500,11 @@ gtk_window_class_init (GtkWindowClass *klass)
                   1,
                   GTK_TYPE_DIRECTION_TYPE);
 
-  window_signals[ACCELS_CHANGED] =
-    g_signal_new ("accels_changed",
+  window_signals[KEYS_CHANGED] =
+    g_signal_new ("keys_changed",
                   G_OBJECT_CLASS_TYPE (object_class),
                   G_SIGNAL_RUN_FIRST,
-                  GTK_SIGNAL_OFFSET (GtkWindowClass, accels_changed),
+                  GTK_SIGNAL_OFFSET (GtkWindowClass, keys_changed),
                   NULL, NULL,
                   gtk_marshal_VOID__VOID,
                   G_TYPE_NONE,
@@ -1042,30 +1042,30 @@ gtk_window_set_policy (GtkWindow *window,
 }
 
 static gboolean
-handle_accels_changed (gpointer data)
+handle_keys_changed (gpointer data)
 {
   GtkWindow *window;
 
   GDK_THREADS_ENTER ();
   window = GTK_WINDOW (data);
 
-  if (window->accels_changed_handler)
+  if (window->keys_changed_handler)
     {
-      gtk_idle_remove (window->accels_changed_handler);
-      window->accels_changed_handler = 0;
+      gtk_idle_remove (window->keys_changed_handler);
+      window->keys_changed_handler = 0;
     }
 
-  g_signal_emit (window, window_signals[ACCELS_CHANGED], 0);
+  g_signal_emit (window, window_signals[KEYS_CHANGED], 0);
   GDK_THREADS_LEAVE ();
   
   return FALSE;
 }
 
 static void
-gtk_window_notify_accels_changed (GtkWindow *window)
+gtk_window_notify_keys_changed (GtkWindow *window)
 {
-  if (!window->accels_changed_handler)
-    window->accels_changed_handler = gtk_idle_add (handle_accels_changed, window);
+  if (!window->keys_changed_handler)
+    window->keys_changed_handler = gtk_idle_add (handle_keys_changed, window);
 }
 
 /**
@@ -1078,15 +1078,15 @@ gtk_window_notify_accels_changed (GtkWindow *window)
  * in @accel_group.
  **/
 void
-gtk_window_add_accel_group (GtkWindow        *window,
-                           GtkAccelGroup    *accel_group)
+gtk_window_add_accel_group (GtkWindow     *window,
+                           GtkAccelGroup *accel_group)
 {
   g_return_if_fail (GTK_IS_WINDOW (window));
-  g_return_if_fail (accel_group != NULL);
+  g_return_if_fail (GTK_IS_ACCEL_GROUP (accel_group));
 
   _gtk_accel_group_attach (accel_group, G_OBJECT (window));
   g_signal_connect_object (accel_group, "accel_changed",
-                          G_CALLBACK (gtk_window_notify_accels_changed),
+                          G_CALLBACK (gtk_window_notify_keys_changed),
                           window, G_CONNECT_SWAPPED);
 }
 
@@ -1098,14 +1098,14 @@ gtk_window_add_accel_group (GtkWindow        *window,
  * Reverses the effects of gtk_window_add_accel_group().
  **/
 void
-gtk_window_remove_accel_group (GtkWindow       *window,
-                              GtkAccelGroup   *accel_group)
+gtk_window_remove_accel_group (GtkWindow     *window,
+                              GtkAccelGroup *accel_group)
 {
   g_return_if_fail (GTK_IS_WINDOW (window));
   g_return_if_fail (accel_group != NULL);
 
   g_signal_handlers_disconnect_by_func (accel_group,
-                                       G_CALLBACK (gtk_window_notify_accels_changed),
+                                       G_CALLBACK (gtk_window_notify_keys_changed),
                                        window);
   _gtk_accel_group_detach (accel_group, G_OBJECT (window));
 }
@@ -1137,7 +1137,7 @@ gtk_window_add_mnemonic (GtkWindow *window,
       mnemonic->targets = g_slist_prepend (NULL, target);
       g_hash_table_insert (mnemonic_hash_table, mnemonic, mnemonic);
     }
-  gtk_window_notify_accels_changed (window);
+  gtk_window_notify_keys_changed (window);
 }
 
 void
@@ -1163,7 +1163,7 @@ gtk_window_remove_mnemonic (GtkWindow *window,
       g_hash_table_remove (mnemonic_hash_table, mnemonic);
       g_free (mnemonic);
     }
-  gtk_window_notify_accels_changed (window);
+  gtk_window_notify_keys_changed (window);
 }
 
 gboolean
@@ -1231,7 +1231,7 @@ gtk_window_set_mnemonic_modifier (GtkWindow      *window,
   g_return_if_fail ((modifier & ~GDK_MODIFIER_MASK) == 0);
 
   window->mnemonic_modifier = modifier;
-  gtk_window_notify_accels_changed (window);
+  gtk_window_notify_keys_changed (window);
 }
 
 /**
@@ -2929,10 +2929,10 @@ gtk_window_finalize (GObject *object)
       g_free (window->geometry_info);
     }
 
-  if (window->accels_changed_handler)
+  if (window->keys_changed_handler)
     {
-      gtk_idle_remove (window->accels_changed_handler);
-      window->accels_changed_handler = 0;
+      gtk_idle_remove (window->keys_changed_handler);
+      window->keys_changed_handler = 0;
     }
 
   G_OBJECT_CLASS (parent_class)->finalize (object);
index 3a6dd6de9e52de12581ef73d6b4ad49901a2ac14..2ebfaea759949964bb716f31d2fb95ab2f0eef5d 100644 (file)
@@ -105,7 +105,7 @@ struct _GtkWindow
   guint frame_right;
   guint frame_bottom;
 
-  guint accels_changed_handler;
+  guint keys_changed_handler;
   
   GdkModifierType mnemonic_modifier;
   gpointer gtk_reserved1;      /* For future GdkScreen * */
@@ -126,7 +126,7 @@ struct _GtkWindowClass
   void     (* activate_default)        (GtkWindow       *window);
   void     (* move_focus)              (GtkWindow       *window,
                                         GtkDirectionType direction);  
-  void    (*accels_changed)           (GtkWindow       *window);
+  void    (*keys_changed)             (GtkWindow       *window);
 };
 
 #define GTK_TYPE_WINDOW_GROUP             (gtk_window_group_get_type ())